/**********************************************
* @file    	i2c_gpio.h
* @author 	dralee
* @version	v1.0
* @date		2021-12-05
* @brief	模拟I2C配置
* 
***********************************************/

#ifndef __I2C_GPIO_H
#define __I2C_GPIO_H

#include <inttypes.h>

#define EEPROM_I2C_WR			0		// 写控制bit
#define EEPROM_I2C_RD			1		// 读控制bit
#define I2C_METHOD_TYPE		Register  // 操作方式

typedef enum
{
	Std_Lib = 0, // 库函数
	Register = 1     // 寄存器方式
} EEPROM_I2C_TypeDef;

// I2C总线连接的GPIO端口，只需要修改以下为任意改变SCL和SDA引脚
#define EEPROM_GPIO_PORT_I2C		GPIOB			// 端口
#define EEPROM_RCC_I2C_PORT			RCC_APB2Periph_GPIOB 	// GPIO端口时钟
#define EEPROM_I2C_SCL_PIN			GPIO_Pin_6						// 连接到SCL时钟线的GPIO
#define EEPROM_I2C_SDA_PIN			GPIO_Pin_7						// 连接到SDA数据线的GPIO

// 根据宏类型操作I2C不同方式
#if I2C_METHOD_TYPE == 1
#define EEPROM_I2C_SCL_1()		GPIO_SetBits(EEPROM_GPIO_PORT_I2C, EEPROM_I2C_SCL_PIN)						// SCL = 1
#define EEPROM_I2C_SCL_0()		GPIO_ResetBits(EEPROM_GPIO_PORT_I2C, EEPROM_I2C_SCL_PIN)					// SCL = 0

#define EEPROM_I2C_SDA_1()		GPIO_SetBits(EEPROM_GPIO_PORT_I2C, EEPROM_I2C_SDA_PIN)						// SDA = 1
#define EEPROM_I2C_SDA_0()		GPIO_ResetBits(EEPROM_GPIO_PORT_I2C, EEPROM_I2C_SDA_PIN)					// SDA = 0

#define EEPROM_I2C_SDA_READ()		GPIO_ReadInputDataBit(EEPROM_GPIO_PORT_I2C, EEPROM_I2C_SDA_PIN)	// 读SAD口线状态 
#else  // 直接寄存器操作实现IO读写
// 注：以下写法，在IAR最高级别优化时，会被编译器错误优化
#define EEPROM_I2C_SCL_1()		EEPROM_GPIO_PORT_I2C->BSRR = EEPROM_I2C_SCL_PIN						// SCL = 1
#define EEPROM_I2C_SCL_0()		EEPROM_GPIO_PORT_I2C->BRR = EEPROM_I2C_SCL_PIN						// SCL = 0

#define EEPROM_I2C_SDA_1()		EEPROM_GPIO_PORT_I2C->BSRR = EEPROM_I2C_SDA_PIN						// SDA = 1
#define EEPROM_I2C_SDA_0()		EEPROM_GPIO_PORT_I2C->BRR = EEPROM_I2C_SDA_PIN						// SDA = 0

#define EEPROM_I2C_SDA_READ()		((EEPROM_GPIO_PORT_I2C->IDR & EEPROM_I2C_SDA_PIN) != 0)	// 读SAD口线状态 
#endif

void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(uint8_t ucByte);
uint8_t I2C_ReadByte(void);
uint8_t I2C_WaitAck(void);
void I2C_Ack(void);
void I2C_NAck(void);
uint8_t I2C_CheckDevice(uint8_t address);

#endif
